﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Net;
using System.Text.RegularExpressions;
using Openapi.Weibo.Model;
using RestSharp;

namespace Openapi.Weibo
{
    public partial class Client
    {
        private Api.RestApi _restApi;

        /// <summary>
        /// 直接用Access_Token实例化(取得访问令牌后)
        /// </summary>
        /// <param name="Token"></param>
        public Client(AccessToken Token)
        {
            _accessToken = Token;
            _restApi = new Api.RestApi()
            {
                Authenticator = new HeaderAuthenticator(_accessToken.access_token)
            };
        }

        /// <summary>
        /// 授权过的Access Token
        /// </summary>
        /// <param name="access_token"></param>
        public Client(String access_token)
        {
            _restApi = new Api.RestApi()
            {
                Authenticator = new HeaderAuthenticator(access_token)
            };
            var TokenInfo = _restApi.SafeExecute<TokenInfo>(new RestRequest 
            {
               
            });
        }

        private AccessToken _accessToken;
        /// <summary>
        /// 访问令牌
        /// </summary>
        public AccessToken AccessToken 
        {
            get
            {
                return _accessToken;
            }
        }

        /// <summary>
        /// 验证accesstoken是否合法
        /// api：account/get_uid
        /// </summary>
        /// <param name="accessToken"></param>
        /// <returns></returns>
        public bool VerifyCredentials(string accessToken)
        {
            if (String.IsNullOrEmpty(accessToken))
                return false;
            var result = this.ExecuteApi<AccountSingle>("account/get_uid.json", Method.GET, new Parameter 
            { 
                Name = "access_token",
                Value=accessToken,
                Type=ParameterType.GetOrPost
            });
            if (!result.IsReturnError)
            {
                return !String.IsNullOrEmpty(result.SuccessData.uid);
            }
            return false;
        }

        /// <summary>
        /// 执行Api返回响应结果
        /// </summary>
        /// <param name="request">
        /// 此时的resource应加上返回格式{path+format}
        /// eg. statuses/public_timeline.json
        /// </param>
        /// <returns></returns>
        public IRestResponse ExecuteApi(IRestRequest request)
        {
            if (_restApi.Authenticator == null)
            {
                throw new ArgumentException("未授权的请求");
            }
            return _restApi.Execute(request);
        }

        /// <summary>
        /// 执行api命令
        /// </summary>
        /// <param name="resource">
        /// Full URL: {BaseUrl}/{resource}
        /// eg. statuses/public_timeline.json
        /// </param>
        /// <param name="httpMethod">
        /// 仅支持GET和POST,不为GET时全部看作POST
        /// </param>
        /// <param name="params"></param>
        /// <returns></returns>
        public IRestResponse ExecuteApi(string resource, Method httpMethod, params Parameter[] @params)
        {
            var request = new RestRequest(resource, httpMethod);
            request.AddRangeParameter(@params);
            return this.ExecuteApi(request);
        }

        /// <summary>
        /// 执行api命令
        /// </summary>
        /// <param name="path">api路径 eg. statuses/public_timeline</param>
        /// <param name="format">返回数据的格式</param>
        /// <param name="httpMethod">请求的类型</param>
        /// <param name="params">请求参数</param>
        /// <returns></returns>
        public IRestResponse ExecuteApi(string path, DataFormat format, Method httpMethod, IDictionary<string, object> @params)
        {
            var resource = (format == DataFormat.Xml) ? path + ".xml" : path + ".json";
            return this.ExecuteApi(resource, httpMethod, @params);
        }

        /// <summary>
        /// 执行api命令
        /// </summary>
        /// <param name="url">api路径+返回类型 eg. statuses/public_timeline.json</param>
        /// <param name="httpMethod">请求的类型</param>
        /// <param name="params">请求参数</param>
        /// <returns></returns>
        public IRestResponse ExecuteApi(string url, Method httpMethod, IDictionary<string, object> @params)
        {
            return this.ExecuteApi(url, httpMethod, @params.ToParameterArry());
        }

        /// <summary>
        /// 执行api命令
        /// </summary>
        /// <typeparam name="T">返回数据的类型</typeparam>
        /// <param name="request"></param>
        /// <returns></returns>
        public IResponseResult<T> ExecuteApi<T>(IRestRequest request) where T : new()
        {
            return _restApi.SafeExecute<T>(request);
        }

        /// <summary>
        /// 执行api命令
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="resource">
        /// Full URL: {BaseUrl}/{resource}
        /// eg. statuses/public_timeline.json
        /// </param>
        /// <param name="httpMethod">
        /// 仅支持GET和POST,不为GET时全部看作POST
        /// </param>
        /// <param name="params">请求参数</param>
        /// <returns></returns>
        public IResponseResult<T> ExecuteApi<T>(string resource, Method httpMethod, params Parameter[] @params) where T : new()
        {
            var request = new RestRequest(resource, httpMethod);
            request.AddRangeParameter(@params);
            return this.ExecuteApi<T>(request);
        }

        /// <summary>
        /// 执行api命令
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path">api路径 eg. statuses/public_timeline</param>
        /// <param name="format">返回数据的格式</param>
        /// <param name="httpMethod">请求的类型</param>
        /// <param name="params">请求参数</param>
        /// <returns></returns>
        public IResponseResult<T> ExecuteApi<T>(string path, DataFormat format, Method httpMethod, IDictionary<string, object> @params) where T : new()
        {
            var resource = (format == DataFormat.Xml) ? path + ".xml" : path + ".json";
            return this.ExecuteApi<T>(resource, httpMethod, @params);
        }

        /// <summary>
        /// 执行api命令
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="url">api路径+返回类型 eg. statuses/public_timeline.json</param>
        /// <param name="httpMethod">请求的类型</param>
        /// <param name="params">请求参数</param>
        /// <returns></returns>
        public IResponseResult<T> ExecuteApi<T>(string url, Method httpMethod, IDictionary<string, object> @params) where T : new()
        {
            return this.ExecuteApi<T>(url, httpMethod, @params.ToParameterArry());
        }

        /// <summary>
        /// 异步执行api命令
        /// </summary>
        /// <param name="request"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        public RestRequestAsyncHandle ExecuteApiAsync(Action<IRestResponse, RestRequestAsyncHandle> callback, IRestRequest request)
        {
            return _restApi.ExecuteAsync(request, callback);
        }

        public RestRequestAsyncHandle ExecuteApiAsync(Action<IRestResponse, RestRequestAsyncHandle> callback, string resource, Method httpMethod, params Parameter[] @params)
        {
            var request = new RestRequest(resource, httpMethod);
            request.AddRangeParameter(@params);
            return _restApi.ExecuteAsync(request, callback);
        }

        public RestRequestAsyncHandle ExecuteApiAsync(Action<IRestResponse, RestRequestAsyncHandle> callback, string path, DataFormat format, Method httpMethod, IDictionary<string, object> @params)
        {
            var resource = (format == DataFormat.Xml) ? path + ".xml" : path + ".json";
            return this.ExecuteApiAsync(callback, resource, httpMethod, @params);
        }

        public RestRequestAsyncHandle ExecuteApiAsync(Action<IRestResponse, RestRequestAsyncHandle> callback, string url, Method httpMethod, IDictionary<string, object> @params)
        {
            return this.ExecuteApiAsync(callback, url, httpMethod, @params.ToParameterArry());
        }

        /// <summary>
        /// 异步执行api命令
        /// </summary>
        /// <param name="request"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        public RestRequestAsyncHandle ExecuteApiAsync<T>(Action<IResponseResult<T>, RestRequestAsyncHandle> callback, IRestRequest request)
        {
            return _restApi.SafeExecuteAsync<T>(request, callback);
        }

        public RestRequestAsyncHandle ExecuteApiAsync<T>(Action<IResponseResult<T>, RestRequestAsyncHandle> callback, string resource, Method httpMethod, params Parameter[] @params)
        {
            var request = new RestRequest(resource, httpMethod);
            request.AddRangeParameter(@params);
            return this.ExecuteApiAsync<T>(callback, request);
        }

        public RestRequestAsyncHandle ExecuteApiAsync<T>(Action<IResponseResult<T>, RestRequestAsyncHandle> callback, string path, DataFormat format, Method httpMethod, IDictionary<string, object> @params)
        {
            var resource = (format == DataFormat.Xml) ? path + ".xml" : path + ".json";
            return this.ExecuteApiAsync<T>(callback, resource, httpMethod, @params);
        }

        public RestRequestAsyncHandle ExecuteApiAsync<T>(Action<IResponseResult<T>, RestRequestAsyncHandle> callback, string url, Method httpMethod, IDictionary<string, object> @params)
        {
            return this.ExecuteApiAsync<T>(callback, url, httpMethod, @params.ToParameterArry());
        }
    }
}
